﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using FacebookLoginButton.Models;

namespace FacebookLoginButton.Controllers
{
    public class InputController : Controller
    {
        //
        // GET: /Input/

        private AccountController account = new AccountController();
        private FacebookContext db = new FacebookContext();
        private static ConnectionChain connection = new ConnectionChain();

        public ActionResult Index()
        {
            return View();
        }

        [HttpPost]
        public ActionResult Search(FacebookUser destination)
        {
            String msg = "The user requested connection to " + destination.id;
            FacebookUser dest;
            if ((dest = db.PlutoUser.Find(destination.id)) == null)
            {
                msg = String.Concat(msg, System.Environment.NewLine + "The user " + destination.id + " is not registered on Pluto");
            }
            else
            {
                String detailsFormat = "The user is looking for {0}. {1} {2} can be contacted at {3}";
                String details = String.Format(detailsFormat, dest.name, dest.first_name, dest.last_name, new Uri(dest.link).AbsoluteUri);
                msg = String.Concat(msg, details);
                connection.SetChain(initializeGraph(msg, dest));
                return RedirectToAction("DisplayChain");
            }
            return this.Content(msg);
        }

        public IEnumerable<FacebookUser> initializeGraph(String msg, FacebookUser destination)
        {
            Graph graph = new Graph();
           
            foreach (FacebookUser user in db.PlutoUser)
            {
                if (graph.exists(user.id) == false)
                {
                    graph.AddNode(user.id);
                }
            }
            foreach (FacebookUser user in db.PlutoUser)
            {
                foreach (FacebookUserFriend relation in user.friendsList)
                {
                    if (graph.exists(relation.FacebookFriendId) == false)
                    {
                        graph.AddNode(relation.FacebookFriendId);
                    }
                }
            }

            foreach (FacebookUserFriend relation in db.PlutoUserFriend)
            {
                if (graph.existsConnection(relation.FacebookUserId, relation.FacebookFriendId) == false)
                {
                    //msg = String.Concat(msg, String.Format("<br><br>{0} friends {1}<br><br>", relation.FacebookUser.name, relation.FacebookFriend.name));
                    graph.AddConnection(relation.FacebookUserId, relation.FacebookFriendId);
                }
            }
            

            string srcId = Session["uid"].ToString();//account.getUserId();
            if (srcId == null)
            {
                msg = String.Concat(msg, "<br><br>Source was null");
                return null;//this.Content(msg);
            }
            string destId = destination.id;

            FacebookUser source = db.PlutoUser.Find(srcId);
            //FacebookUser source = srcRelation.FacebookUser;

            msg = String.Concat(msg, "<br><br>-----------------------Connection------------------<br><br>");
            msg = String.Concat(msg, String.Format("<br><br>{0} -------------------- {1}<br><br>", srcId, destId));
            msg = String.Concat(msg, String.Format("<br><br>{0} -------------------- {1}<br><br>", source.name, destination.name));

            var calculator = new DistanceCalculator();
            var distances = calculator.CalculateDistances(graph, /*destination.id*/srcId/**/);  // Start from "G"

            Node dest;
            List<FacebookUser> chain = new List<FacebookUser>();

            if (graph.Nodes.TryGetValue(destination.id, out dest))
            {
                FacebookUser node = db.PlutoUser.Find(dest.Name);
                if (node != null)
                {
                    chain.Insert(0, node);
                }
                else
                {
                    msg = String.Concat(msg, String.Format("<br><br> {0} not found <br><br>", dest.Name));

                }
                Node parent = dest.Parent;
                while (parent != null)
                {
                    node = db.PlutoUser.Find(parent.Name);
                    if (node != null)
                    {
                        chain.Insert(0, node);
                    }
                    else
                    {
                        msg = String.Concat(msg, String.Format("<br><br> {0} not found <br><br>", parent.Name));
                    } 
                    parent = parent.Parent;
                }
            }

            foreach (var d in distances)
            {
                msg = String.Concat(msg, String.Format("{0}, {1}   <br>", d.Key, d.Value));
            }

            if (distances[destination.id] == int.MaxValue)
            {
                msg = String.Concat(msg, "NO CONNECTION");
            }
            else
            {

               msg = String.Concat(msg, "<br><br>-----------------------Chain------------------<br><br>");

                foreach (FacebookUser node in chain)
                {
                    msg = String.Concat(msg, String.Format("{0} ---> ", node.name));
                }

                //return this.Content(msg);
            }
            //return this.Content(msg);
            return chain;
        }

        public ActionResult DisplayChain(IEnumerable<FacebookUser> chain)
        {
            if (connection.GetChain() == null)
                return this.Content("chain is null");
            else
                chain = connection.GetChain();
            return View(chain);
        }
    }
}
